<?php

namespace houniao;

use catchAdmin\api\model\Order;
use catchAdmin\customs\model\HnOrderDetail;
use catchAdmin\externalGoods\model\MessageQueue;
use catchAdmin\externalGoods\model\NewNotify;
use catchAdmin\externalGoods\model\TenantGoods;
use catchAdmin\externalGoods\service\GoodsService;
use catchAdmin\externalGoods\model\Notify as externalNotify;
//use catcher\base\CatchRequest as Request;
use catchAdmin\externalGoods\service\OrderLogisticsTrackService;
use catchAdmin\externalGoods\service\OrderService;
use houniao\api\v1\Goods;
use think\facade\Db;
use think\Request;
use catcher\CatchResponse;
use houniao\tools\Params;
use think\Exception;
use think\facade\Log;

class Notify
{
    protected $redis;
    
    public function __construct()
    {
        $this->redis = new \Redis();
        $this->redis->connect('127.0.0.1', 6379);
        $this->redis->auth(config('cache.stores.redis.password'));
    }

//    protected $app_key = '2f5bb2157a9f810d';
//    protected $secret='b37682554865a6deb1cc347b0b9ec7da';
    protected $app_key = '62ae4e5e226a972c';
    protected $secret='2b7db6bdb6cc689de3cda48a4fe80095';

    const GOODS_ADD = 'goods.add';//商品新增
    const GOODS_UPD = 'goods.update';//商品更新
    const GOODS_SHELVE = 'goods.shelve';//商品上架
    const GOODS_UNSHELVE = 'goods.unshelve';//商品下架
    const GOODS_PRICE = 'goods.price';//商品价格库存
    const GOODS_STOCK = 'goods.stock';//商品库存
    const ORDER_SEND = 'order.send';//订单发货
    const ORDER_STATUS = 'order.status';//订单状态更新
//    const AFTER_SALE_STATUS = 'after.sale.status';//售后处理更新
    const ORDER_TRACK = 'track.info';//物流通知

    public function notify(Request $request){
        $data = $request->post();

//        $data = '{"type":"order.status","data":{"order_no":"2024082880966","order_status":"1","customs_time":"1724812825","source_order_no":"17155727344303023_1"},"sign":"0aa2b0f9d290e5576f1c97bbfd37156e"}';
//        $data = json_decode($data,true);

//        $data = '{"type":"goods.stock","data":{"goods_spu":"HK00002500","goods_name":"1","old_goods_spu":""},"sign":"38fdae0eef50dca64aaf7d3f915f8f10"}';
//        $data = json_decode($data,true);


////物流
//        $data = '{
//  "type": "track.info",
//  "data": {
//    "order_no": "1",
//    "express_no": "1"
//  },
//  "sign": "a6127e2a86e6d68c03f0556ad3c96976"
//}';
//                $data = json_decode($data,true);

//        //订单发货
//        $data = '{"type":"order.send","data":{"source_order_no":"2","order_no":"3","express":[{"express_no":"1","express_name":"1","express_code":"1","delivery_time":"1687324840","goods_num":"1","goods_spu":"1","sku_id":"1","sku_name":"1"}],"order_goods":[{"express_no":"1","express_name":"1","express_code":"1","delivery_time":"1687324840","goods_num":"1","goods_spu":"1","sku_id":"1","sku_name":"1"}]},"sign":"3070f7ee378168c4586975a5b4f800f9"}';
//        $data = json_decode($data,true);


//        //商品新增
//        $data = '{"type":"goods.add","data":{"goods_spu":"BS00033612","goods_name":"Swisse/瑞思 血橙亮白粘土泥面膜 70g","old_goods_spu":""},"sign":"fb06c3d0c0cefc1735a110ac927e9d82"}';
//        $data = json_decode($data,true);

//        //物流通知
//        $data = '{"type":"track.info","data":{"order_no":"2023122845406","express_no":"YT2512270068123"},"sign":"17f307a22011134829c82654fa61ef77"}';
//        $data = json_decode($data,true);

        $remark = '';

        if(!array_key_exists('sign',$data) || !$this->checkSign($data,$data['sign'])){
            $remark = 'sign错误';
            die(json_encode([
                'code'=>-1,
                'msg'=>'sign错误'
            ],JSON_UNESCAPED_UNICODE));
        }

//        //判断是否操作过
//        $notifyModel = new externalNotify();
//        $notifyIsExist = $notifyModel->where([
//            'status'=>1,
//            'sign'=>$data['sign']
//        ])->value('id');
//        if(!empty($notifyIsExist)){
//            die(json_encode([
//                'code'=> 200,
//                'msg'=> '商品更新回调成功'
//            ],JSON_UNESCAPED_UNICODE));
//        }

//        die(json_encode([
//            'code'=> 200,
//            'msg'=> '商品更新回调成功ff1'
//        ],JSON_UNESCAPED_UNICODE));

        //开始具体业务逻辑
        $goodsService = new GoodsService;
        $logisticService = new OrderLogisticsTrackService;
        $orderService = new OrderService;
        $msg = '';
        $result = 0;

        //过滤一下 如果是商品类型的通知
        if(in_array($data['type'],[
            self::GOODS_ADD ,
            self::GOODS_UPD ,
            self::GOODS_SHELVE,
            self::GOODS_UNSHELVE,
            self::GOODS_PRICE,
            self::GOODS_STOCK])){

            //商品类型通知 如果是保税的，不用处理，直接返回成功
            if (strpos($data['data']['goods_spu'], 'BS') === 0) {
                die(json_encode([
                    'code'=> 200,
                    'msg'=> $msg . '回调成功'
                ],JSON_UNESCAPED_UNICODE));
            }

            // 然后将商品通知数据存入Redis队列
            $redisKey = 'goods_notify_queue';
            
            // 生成唯一标识
            $uniqueKey = "goods_notify:{$data['type']}:{$data['data']['goods_spu']}";
            
            // 检查是否已存在相同的通知
            if (!$this->redis->sIsMember('goods_notify_set', $uniqueKey)) {
                // 检查Set是否存在并设置过期时间
                if (!$this->redis->exists('goods_notify_set')) {
                    // Set不存在时,创建并设置过期时间
                    $this->redis->multi();
                    $this->redis->sAdd('goods_notify_set', $uniqueKey);
                    $this->redis->expire('goods_notify_set', 86400);
                    $this->redis->exec();
                } else {
                    // Set已存在,直接添加元素
                    $this->redis->sAdd('goods_notify_set', $uniqueKey);
                }

                // 记录日志
                $notifyData = [
                    'type'=>$data['type'],
                    'type_name'=>$this->getTypeName($data['type']),
                    'status'=> 1,
                    'notify_data'=>json_encode($data['data']),
                    'remark'=>'已加入Redis队列',
                    'sign'=>$data['sign']
                ];
                $notifyModel = new externalNotify();
                $notifyModel->save($notifyData);
                
                // 将通知数据放入队列
                $this->redis->lPush($redisKey, json_encode([
                    'type' => $data['type'],
                    'data' => $data['data'],
                    'created_at' => time(),
                    'notify_id' => $notifyModel->id,
                    'unique_key' => $uniqueKey
                ]));
            }

            die(json_encode([
                'code'=> 200,
                'msg'=> '回调成功'
            ],JSON_UNESCAPED_UNICODE));
        }

        Db::startTrans();
        try {
            switch ($data['type']){
                case self::GOODS_ADD:
                    $msg = '商品新增';
                    $result=  $goodsService->notifyGoodsAdd($data['data']);
                    $goodsService->goodsSubscribe($data['data']['goods_spu']);//商品订阅
                    break;
                case self::GOODS_UPD:
                    $msg = '商品更新';
                    $result = $goodsService->notifyGoodsUpdate($data['data']);
                    break;
                case self::GOODS_SHELVE:
                    $msg = '商品上架';
                    $result = $goodsService->notifyGoodsShelve($data['data']);
                    break;
                case self::GOODS_UNSHELVE:
                    $msg = '商品下架';
//                    $result = $goodsService->notifyGoodsUnShelveBySPU($data['data']['goods_spu']);
                    $result = $goodsService->notifyGoodsUnShelveBySPU($data['data']);
                    break;
                case self::GOODS_PRICE:
                    $msg = '商品价格库存更新';
                    $result = $goodsService->notifyGoodsPrice($data['data']);
                    break;
                case self::GOODS_STOCK:
                    $msg = '商品库存更新';
                    $result = $goodsService->notifyGoodsStock($data['data']);
                    break;
                case self::ORDER_TRACK:
                    $msg = '物流通知';
                    $result = $logisticService->notifyTrack($data['data']);
                    break;
                case self::ORDER_SEND:
                    $msg = '订单发货通知';
                    $result = $logisticService->notifySend($data['data']);
                    break;
                case self::ORDER_STATUS:
                    $msg = '订单状态更新通知';
                    $result = $orderService->notifyOrderStatusSend($data['data']);
                    break;
                default:
                    $msg = '未知';
                    $result = false;
            }

            if(in_array($data['type'],[self::ORDER_STATUS , self::ORDER_SEND , self::ORDER_TRACK])){//订单
                $main_order_id = '';
                if(array_key_exists('source_order_no',$data['data'])){//来源订单编号
                    $explode = explode('_', $data['data']['source_order_no']);

                    $main_order_id = $explode[0];
//                    $tenant_id = (new Order)->where('orderId',$data['data']['source_order_no'])->value('tenant_id');
                    $tenant_id = (new Order)->where('orderId',$main_order_id)->value('tenant_id');
                }elseif (array_key_exists('order_no',$data['data'])){
                    $tenant_id = (new HnOrderDetail())->where('order_no',$data['data']['order_no'])->value('tenant_id');
                }

                if(!empty($tenant_id)){//确定是商户下的单的话
                    //给专属商户发通知
                    $copyData = $data;
                    if('' != $main_order_id){
                        $copyData['data']['source_order_no'] = $main_order_id;
                    }
                    //$this->addMessage($data,5,$tenant_id);//5次机会
                    $this->addMessage($copyData,5,$tenant_id);//5次机会
                }else{
                    die('未知订单');
                }
            }else{
                if(true === $result){ //有问题就不发了
                    //给所有商户发通知
                    $this->addMessage($data,5);//5次机会
                }
            }

            Db::commit();
        } catch (\Exception $exception) {
//            Log::write(json_encode($exception->getMessage()));
            $remark = $exception->getMessage();
//            throw new Exception($exception->getMessage());
            Db::rollback();
        }

        if(!is_bool($result)){
            $remark = $result;
            $result = 1;
        }

        //记录日志
        $notifyData = [
            'type'=>$data['type'],
            'type_name'=>$msg,
            'status'=> (int)$result ,//success,
            'notify_data'=>json_encode($data['data']),
            'remark'=>$remark,
            'sign'=>$data['sign']
        ];

        $notifyModel = new externalNotify();
        $notifyModel->save($notifyData);

//        //测试分表
//        $newNotify = new NewNotify;
//        $newNotify->addRecord($notifyData);

        if($result){
            die(json_encode([
                'code'=> 200,
                'msg'=> $msg . '回调成功'
            ],JSON_UNESCAPED_UNICODE));
        }

        die(json_encode([
            'code'=> -1,
            'msg'=> '失败le'
        ],JSON_UNESCAPED_UNICODE));
    }

    public function test(Request $request){
        //dd($request->post());
        die('success');
    }

    //检验sign
    public function checkSign($data,$request_sign)
    {
        $data['app_key'] = $this->app_key;

        $data =  Params::paraFilter($data);

        //对待签名参数数组排序
        $old = $data;
        $data = Params::argSort($data);

        //生成签名结果
        $makeSign = Params::buildRequestMysign($data,$this->secret);

        if ($makeSign == $request_sign) {
            return true;
        } else {
            return false;
        }
    }

    //添加消息
    public function addMessage($message,$retries=0,$tenant_id = null,$priority=0){
        unset($message['sign']);
        $messageQueue = new MessageQueue;

        $data = [];
        //拿到所有商户数据，后期重新搞
        $list = [
            ['tenant_id'=>'10043','notify_url'=>'http://cross.qekj.net'],
            ['tenant_id'=>'10050','notify_url'=>'https://gateway.jsbcmall.com/app/callback/ltMessage'],
            ['tenant_id'=>'10143','notify_url'=>'http://cross.qekj.net/callback/SyncShop'],
//            ['tenant_id'=>'10144','notify_url'=>'http://cross.qekj.net/callback/SyncShop1110'],
            ['tenant_id'=>'10146','notify_url'=>'http://testpssnotify.indoorbuy.com/Notify/index/userType/shoplongtan/messageType/OrderExpress'],
            ['tenant_id'=>'10147','notify_url'=>'http://cross.qekj.net/callback/SyncShop1116'],
            ['tenant_id'=>'10161','notify_url'=>'http://cross.qekj.net/callback/SyncShop1122'],
            ['tenant_id'=>'10159','notify_url'=>'http://cross.qekj.net/callback/SyncShop1125'],
            // ['tenant_id'=>'10170','notify_url'=>'http://cross.qekj.net/callback/SyncShop1127'],
        ];

        //商品类型通知
        if(array_key_exists('data',$message) && array_key_exists('goods_spu',$message['data'])){
            foreach ($list as $key => $value){
                //判断小池子是否选择了商品
                $find = (new TenantGoods())->where([
                    'tenant_id'=>$value['tenant_id'],
                    'goods_spu'=>$message['data']['goods_spu']
                ])->find();
                if(!$find) {
                    unset($list[$key]);
                }
            }
        }

        //只发送给对应商户
        if(null !== $tenant_id){
            $new_list = array_column($list,null,'tenant_id');
            $list = [$new_list[$tenant_id]];
        }

        foreach ($list as $value){
            $message['sign'] = $this->_makeSign($message);
            $message['request_url'] = $value['notify_url'];
            $data[] = [
                'message'=>$message,
                'retries'=>$retries,
                'priority'=>$priority,
                'to_tenant_id'=>$value['tenant_id']
            ];
        }

        $result =  $messageQueue->saveAll($data);
        if(!$result){
            throw new Exception('消息添加失败');
        }
    }

    protected function _makeSign($data){

        return md5(stripslashes(json_encode($data,JSON_UNESCAPED_UNICODE)));
    }

    //人脸机器，设备代码
    public function getDeviceCode($id,Request $request){
        $device_id = $id;

        $arr = [
            '1e843749d1127b9a' => '35CX-7WPC-LJAL-RPVN',
//            '43741452ab8426f4' => 'VDVU-AUCX-NVTS-RSZX',
            '43741452ab8426f4' => 'TXD6-YLQT-XV8E-8GCW',
            '8662bb7c865f6314' => '8HDJ-YSXE-CV99-BDRL',
            '84c5a69307bb471' => 'FTMP-HMD7-RXYX-GZFW',
            '7b3f5c3f2aac1721' => 'CFZX-FNP9-6G6Q-TXAN',
            '1d6c6c7c4aa7c736'=> 'J7X8-G5LR-6DXZ-CGWX',
            'c421a82d8b894df7'=> '5DEH-EWGC-HASA-USPN',
            '67c79ff5f77faaf1'=> 'X9J8-PHXS-XPXC-XXXF',
            '6809ccd6871f1cb0'=> 'F89T-GHXG-RAEJ-HHX2',
            '2a1e9cfd3f169eef'=> 'XGDY-7NXY-HMJK-UXLN',
            'eb14335a95d40de4'=> 'VJE8-BGKL-LXJR-XRXB',
            'cf9d795e8253bd70'=> '3BG2-TXP9-BKVP-XNPX',
            '78oe7dd5967b506b'=> '7GTG-FNQP-N5XX-DBYX',
            '6T6Da82440a191d'=> '5K5V-XPLX-QWX3-UL7X',
            '253683360b152d50'=> 'KYXS-SFJR-WDZX-MLGC',
            '78ce7dd5967b506b'=> 'VVW5-XXP7-38CH-ZNCC',
            '6ff6ba8244baf9fd'=> 'VXFX-ASFL-HH44-AC8N',
            '1f53bddcff28f148'=> 'MQRE-LXMB-RBLC-SF52',
            '7c1099425700557'=> 'KNFE-Z6XN-6XCQ-AXDN'
        ];

        if(array_key_exists($device_id,$arr)){
            return CatchResponse::success($arr[$device_id],'授权码获取成功');
        }else{
            return CatchResponse::fail('设备ID不存在！');
        }
    }

    // 获取通知类型名称
    protected function getTypeName($type)
    {
        $typeNames = [
            self::GOODS_ADD => '商品新增',
            self::GOODS_UPD => '商品更新',
            self::GOODS_SHELVE => '商品上架',
            self::GOODS_UNSHELVE => '商品下架',
            self::GOODS_PRICE => '商品价格库存更新',
            self::GOODS_STOCK => '商品库存更新',
        ];

        return $typeNames[$type] ?? '未知';
    }
}